package com.droid.lib.controls.widget;

import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.text.Layout;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.ForegroundColorSpan;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;


import com.droid.lib.controls.R;

import java.util.ArrayList;
import java.util.List;

/**
 * 雷达图控件
 * Created by lixiancheng on 2017/9/18.
 */

public class XRadarView extends View {
    /**
     * 雷达图效果
     */
    private List<RedarItem> mlistRedarItems;
    /**
     * 设置有多少条线
     */
    private int redarItemCount;
    // 几边形雷达
    private int count = 5;

    private int layerCount = 6;  // 层数
    private int drawableSize = 40;
    private int drawablePadding = 10;
    private int descPadding = 5;

    private int titleSize = 40;
    private int dataSize = 30;

    private float radarPercent = 0.7f;

    private int startColor = Color.parseColor("#ff6b6975");
    private int endColor = Color.parseColor("#ff5b5965");
    /**
     * 蜘蛛网线的颜色
     */
    private int cobwebColor;
    /**
     * 圆心与各顶点连线颜色
     */
    private int lineColor;

    /**
     * 标题文本颜色
     */
    private int titleColor;

    /**
     * 圆点半径大小
     */
    private int pointRadius;
    /**
     * 边界线的宽度
     */
    private int boundaryWidth;
    /**
     * 半径线的颜色
     */
    private int radiusColor;
    /**
     * 雷达图渐变颜色数组
     */
    private int[] shaderColors;
    /**
     * 雷达图渐变颜色各种颜色分布的位置
     */
    private float[] shaderPositions;


    /**
     * 是否画边界线
     */
    private boolean enabledBorder = false;
    /**
     * 是否开启动画
     */
    private boolean enabledAnimation = true;
    /**
     * 动画时长
     */
    private int animDuration = 1000;
    /**
     * 是否显示圆点
     */
    private boolean enabledShowPoint = true;
    /**
     * 是否绘制网格
     */
    private boolean enabledPolygon = true;
    /**
     * 是否绘制渐变环
     */
    private boolean enabledShade = true;
    /**
     * 是否绘制半径
     */
    private boolean enabledRadius = true;
    /**
     * 是否绘制文本
     */
    private boolean enabledText = true;
    /**
     * 是否显示标题Pop
     */
    private boolean enabledTitlePop = true;
    /**
     * 是否显示子标题Pop
     */
    private boolean enabledCirclePop = true;
    /**
     * 是否将雷达区域绘制成渐变色
     */
    private boolean enabledRegionShader = false;

    /**
     * 文字最大允许宽度
     */
    private int MAX_TEXT_WIDTH;  //

    /**
     * 每条边对应的圆心角
     */
    private float angle;
    /**
     * 圆心x
     */
    private int centerX;
    /**
     * 圆心y
     */
    private int centerY;
    /**
     * 半径
     */
    private float radius;

    /**
     * 外轮廓是否是圆形
     */
    private boolean isCircle = false;

    /**
     * 区域渐变shader
     */
    private Shader regionShader;

    private Paint cobwebPaint;
    private Paint linePaint;

    private TextPaint titlePaint;
    private Paint layerPaint;
    private Paint radiusPaint;
    private Paint titlePopPaint;


    /**
     * 当前缩放比
     */
    private float currentScale;
    /**
     * 标题点击位置
     */
    private List<Rect> titleRects;
    /**
     * 图标
     */
    private int drawables[];
    /**
     * 标题
     */
    CharSequence titles[];
    /**
     * 各个标题下面的数值文本
     */
    CharSequence values[];
    /**
     * 区域颜色
     */
    int colors[];
    private int mintDataColor = 0;
    private int mintSingleColor = 0;
    private int mintPointColor = 0;
    private int mintBorderColor = 0;
    private int mintSelectParent = -1;
    private int mintSelectChild = -1;
    private int mintSelectX = -1;
    private int mintSelectY = -1;
    private View mvTitlePop;
    private Bitmap mbtTitlePop;

    public XRadarView(Context context) {
        this(context, null, 0);
    }

    public XRadarView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public XRadarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray = context.getResources().obtainAttributes(attrs, R.styleable.XRadarView);
        count = typedArray.getInteger(R.styleable.XRadarView_count, 6);
        layerCount = typedArray.getInteger(R.styleable.XRadarView_layerCount, 6);
        drawableSize = typedArray.getDimensionPixelSize(R.styleable.XRadarView_mDrawableSize, 40);
        drawablePadding = typedArray.getDimensionPixelSize(R.styleable.XRadarView_mDrawablePadding, 10);
        descPadding = typedArray.getDimensionPixelSize(R.styleable.XRadarView_descPadding, 5);
        titleSize = typedArray.getDimensionPixelSize(R.styleable.XRadarView_titleSize, 40);
        dataSize = typedArray.getDimensionPixelSize(R.styleable.XRadarView_dataSize, 30);
        radarPercent = typedArray.getFloat(R.styleable.XRadarView_radarPercent, 0.7f);
        startColor = typedArray.getColor(R.styleable.XRadarView_startColor, Color.parseColor("#ff6b6975"));
        endColor = typedArray.getColor(R.styleable.XRadarView_endColor, Color.parseColor("#ff5b5965"));

        cobwebColor = typedArray.getColor(R.styleable.XRadarView_cobwebColor, Color.parseColor("#ffffffff"));
        lineColor = typedArray.getColor(R.styleable.XRadarView_lineColor, Color.parseColor("#ffffffff"));
        mintDataColor = typedArray.getColor(R.styleable.XRadarView_dataColor, Color.parseColor("#00000000"));
        mintSingleColor = typedArray.getColor(R.styleable.XRadarView_singleColor, Color.RED);
        titleColor = typedArray.getColor(R.styleable.XRadarView_titleColor, Color.parseColor("#80000000"));
        mintPointColor = typedArray.getColor(R.styleable.XRadarView_pointColor, Color.parseColor("#80333366"));
        mintBorderColor = typedArray.getColor(R.styleable.XRadarView_borderColor, Color.RED);
        radiusColor = typedArray.getColor(R.styleable.XRadarView_radiusColor, Color.parseColor("#80CCCCCC"));
        boundaryWidth = typedArray.getDimensionPixelSize(R.styleable.XRadarView_boundaryWidth, 5);

        pointRadius = typedArray.getDimensionPixelSize(R.styleable.XRadarView_pointRadius, 10);
        enabledBorder = typedArray.getBoolean(R.styleable.XRadarView_enabledBorder, false);
        enabledAnimation = typedArray.getBoolean(R.styleable.XRadarView_enabledAnimation, true);
        enabledShowPoint = typedArray.getBoolean(R.styleable.XRadarView_enabledShowPoint, true);
        enabledPolygon = typedArray.getBoolean(R.styleable.XRadarView_enabledPolygon, true);
        enabledShade = typedArray.getBoolean(R.styleable.XRadarView_enabledShade, true);
        enabledText = typedArray.getBoolean(R.styleable.XRadarView_enabledText, true);
        enabledTitlePop = typedArray.getBoolean(R.styleable.XRadarView_enabledTitlePop, true);
        enabledCirclePop = typedArray.getBoolean(R.styleable.XRadarView_enabledTitlePop, true);
        animDuration = typedArray.getInteger(R.styleable.XRadarView_animDuration, 1000);

        typedArray.recycle();

        titleRects = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            titleRects.add(null);
        }

        angle = (float) (Math.PI * 2 / count);

        cobwebPaint = new Paint();
        cobwebPaint.setColor(cobwebColor);
        cobwebPaint.setAntiAlias(true);
        cobwebPaint.setStyle(Paint.Style.STROKE);

        linePaint = new Paint();
        linePaint.setColor(lineColor);
        linePaint.setAntiAlias(true);
        linePaint.setStrokeWidth(4);
        linePaint.setStyle(Paint.Style.STROKE);


        titlePaint = new TextPaint();
        titlePaint.setTextSize(dataSize);
        titlePaint.setColor(titleColor);
        titlePaint.setAntiAlias(true);

        layerPaint = new Paint();
        layerPaint.setAntiAlias(true);
        layerPaint.setStyle(Paint.Style.FILL_AND_STROKE);

        radiusPaint = new Paint();
        radiusPaint.setStyle(Paint.Style.FILL);
        radiusPaint.setAntiAlias(true);
        radiusPaint.setStrokeWidth(3);
        radiusPaint.setColor(radiusColor);

        titlePopPaint = new Paint();
        titlePopPaint.setStyle(Paint.Style.FILL);
        titlePopPaint.setAntiAlias(true);

        colors = new int[count];//几个区域不同的颜色
        drawables = new int[count];
        titles = new CharSequence[count];
        values = new CharSequence[count];


        loadAnimation(enabledAnimation);
        mlistRedarItems = new ArrayList<>();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        radius = Math.min(h, w) / 2 * radarPercent;
        MAX_TEXT_WIDTH = (int) (Math.min(h, w) / 2 * (1 - radarPercent));
        //中心坐标
        centerX = w / 2;
        centerY = h / 2;
        postInvalidate();
        super.onSizeChanged(w, h, oldw, oldh);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int wSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        int hSpecSize = MeasureSpec.getSize(heightMeasureSpec);

        setMeasuredDimension(Math.min(wSpecSize, hSpecSize), Math.min(wSpecSize, hSpecSize));
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        if (regionShader == null && shaderColors != null) {
            regionShader = new LinearGradient(getLeft(), getTop(), getRight(), getBottom(), shaderColors, shaderPositions, Shader.TileMode.CLAMP);
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (enabledShade) {//绘制渐变环
            drawLayer(canvas, startColor, endColor);
        } else {
            drawLayer(canvas, startColor, startColor);
        }
        if (enabledPolygon) {//绘制网格
            drawPolygon(canvas);
        }
        if (enabledText) {
            drawText(canvas);
        }
        if (enabledRadius) {
            drawRadius(canvas);
        }
        for (int i = 0; i < mlistRedarItems.size(); i++) {
            if (!mlistRedarItems.get(i).isShow()) {
                continue;
            }
            //画点
            if (colors == null || colors.length == 0) {
                drawRegion(i, canvas, currentScale);
            } else {
                drawRegionWithColor(i, canvas, currentScale);
            }
            if (enabledBorder) {//画边界线
                drawBorder(i, canvas, currentScale);
            }
            if (enabledShowPoint) {//圆点
                drawPoint(i, canvas, currentScale);
            }
        }
        if (enabledTitlePop) {
            drowTitlePop(canvas);
        }

    }

    private void drawBorder(int position, Canvas canvas, float scale) {
        RedarItem item = mlistRedarItems.get(position);
        float curX, curY;
        float nextX, nextY;
        for (int i = 0; i < count - 1; i++) {
            curX = (float) (centerX + Math.cos(angle * i + Math.PI / 2) * radius * item.getPercents()[i] * scale);
            curY = (float) (centerY - Math.sin(angle * i + Math.PI / 2) * radius * item.getPercents()[i] * scale);

            nextX = (float) (centerX + Math.cos(angle * (i + 1) + Math.PI / 2) * radius * item.getPercents()[i + 1] * scale);
            nextY = (float) (centerY - Math.sin(angle * (i + 1) + Math.PI / 2) * radius * item.getPercents()[i + 1] * scale);

            canvas.drawLine(curX, curY, nextX, nextY, item.getBorderPaint());
        }

        curX = (float) (centerX + Math.cos(angle * (count - 1) + Math.PI / 2) * radius * item.getPercents()[count - 1] * scale);
        curY = (float) (centerY - Math.sin(angle * (count - 1) + Math.PI / 2) * radius * item.getPercents()[count - 1] * scale);
        nextX = (float) (centerX + Math.cos(angle * 0 + Math.PI / 2) * radius * item.getPercents()[0] * scale);
        nextY = (float) (centerY - Math.sin(angle * 0 + Math.PI / 2) * radius * item.getPercents()[0] * scale);
        canvas.drawLine(curX, curY, nextX, nextY, item.getBorderPaint());

    }

    private void drowTitlePop(Canvas canvas) {
        if (mintSelectX == -1 || mintSelectY == -1) {
            return;
        }
        int viewWidth = getWidth();
        int viewHeight = getHeight();
        int btPopWidth = mbtTitlePop.getWidth();
        int btPopHeight = mbtTitlePop.getHeight();
        int thisW = mintSelectX;
        int thisH = mintSelectY;
        int myLeft;
        int myTop;
        if ((viewWidth - (btPopWidth + thisW)) > 0) {
            myLeft = thisW;
        } else {
            myLeft = thisW - btPopWidth;
        }
        if (viewHeight - (btPopHeight + thisH) > 0) {
            myTop = thisH;
        } else {
            myTop = thisH - btPopHeight;
        }
        canvas.drawBitmap(mbtTitlePop, myLeft, myTop, titlePopPaint);
    }

    /**
     * 圆点
     *
     * @param canvas
     * @param scale
     */
    private void drawPoint(int position, Canvas canvas, float scale) {
        RedarItem item = mlistRedarItems.get(position);
        for (int i = 0; i < count; i++) {
            int x, y;
            x = (int) (centerX + scale * item.getPercents()[i] * radius * Math.cos(angle * i + Math.PI / 2));
            y = (int) (centerY - scale * item.getPercents()[i] * radius * Math.sin(angle * i + Math.PI / 2));
            if (mintSelectParent == i && mintSelectChild == position) {
                int radius = (int) (pointRadius * 1.5);
                canvas.drawCircle(x, y, radius, item.pointPaint);
            } else {
                canvas.drawCircle(x, y, pointRadius, item.pointPaint);
            }
            int radius = pointRadius * 2;
            Rect rect = new Rect(x - radius, y - radius, x + radius, y + radius);
            item.getCircleRects().set(i, rect);
        }
    }

    // 画圆心与顶点的连线
    private void drawRadius(Canvas canvas) {
        for (int i = 0; i < count; i++) {
            canvas.drawLine(centerX, centerY, (float) (centerX + Math.cos(angle * i + Math.PI / 2) * radius), (float) (centerY - Math.sin(angle * i + Math.PI / 2) * radius), radiusPaint);
        }
    }

    // 画蜘蛛网
    private void drawPolygon(Canvas canvas) {
        Path path = new Path();
        float r = radius / layerCount;
        for (int i = layerCount; i >= 1; i--) {
            float curR = r * i;
            path.reset();
            if (isCircle) {
                path.addCircle(centerX, centerY, curR, Path.Direction.CW);
            } else {
                for (int j = 0; j < count; j++) {
                    if (j == 0) {
                        path.moveTo(centerX, centerY - curR);
                    } else {
                        path.lineTo((float) (centerX + Math.cos(angle * j + Math.PI / 2) * curR), (float) (centerY - Math.sin(angle * j + Math.PI / 2) * curR));
                    }
                }
                path.close();
            }
            canvas.drawPath(path, cobwebPaint);
        }
    }

    // 画 各层的颜色
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private void drawLayer(Canvas canvas, int startColor, int endColor) {
        Path path = null;
        Path prePath = null;
        float r = radius / layerCount;
        for (int i = layerCount; i >= 0; i--) {
            float curR = r * i;
            path = new Path();
            for (int j = 0; j < count; j++) {
                if (isCircle) {
                    path.addCircle(centerX, centerY, curR, Path.Direction.CW);
                } else {
                    if (j == 0) {
                        path.moveTo(centerX, centerY - curR);
                    } else {
                        path.lineTo((float) (centerX + Math.cos(angle * j + Math.PI / 2) * curR), (float) (centerY - Math.sin(angle * j + Math.PI / 2) * curR));
                    }
                }
            }

            if (prePath != null) {
                if (i % 2 == 1) {
                    prePath.op(path, Path.Op.DIFFERENCE);
                    prePath.close();
                    // 计算渐变颜色
//                    int a0 = Color.alpha(startColor);
//                    int r0 = Color.red(startColor);
//                    int g0 = Color.green(startColor);
//                    int b0 = Color.blue(startColor);
//                    int a1 = Color.alpha(endColor);
//                    int r1 = Color.red(endColor);
//                    int g1 = Color.green(endColor);
//                    int b1 = Color.blue(endColor);
//                    int a2 = (int) (1.0 * i * (a1 - a0) / layerCount + a0);
//                    int r2 = (int) (1.0 * i * (r1 - r0) / layerCount + r0);
//                    int g2 = (int) (1.0 * i * (g1 - g0) / layerCount + g0);
//                    int b2 = (int) (1.0 * i * (b1 - b0) / layerCount + b0);
//                    layerPaint.setColor(Color.argb(a2, r2, g2, b2));
                    layerPaint.setColor(endColor);
                    canvas.drawPath(prePath, layerPaint);
                } else {
                    prePath.close();
                    layerPaint.setColor(startColor);
                    canvas.drawPath(prePath, layerPaint);
                }
            }
            prePath = path;

        }
    }

    // 画 文字和图标
    private void drawText(Canvas canvas) {
        Paint.FontMetrics fontMetrics = titlePaint.getFontMetrics();
        if (titles == null || titles.length == 0) {
            return;
        }
        for (int i = 0; i < count; i++) {
            float x = 0f, y = 0f, curAngle;

            x = (float) (centerX + (radius) * Math.cos(angle * i + Math.PI / 2));
            y = (float) (centerY - (radius) * Math.sin(angle * i + Math.PI / 2));
            curAngle = (float) (angle * i + Math.PI / 2);
            // 取余 在0-2PI范围内
            curAngle = (float) (curAngle % (2 * Math.PI));
            SpannableString ss;
            if (titles[i] instanceof SpannableString) {
                ss = (SpannableString) titles[i];
            } else {
                if (values == null || values[i] == null) {
                    ss = new SpannableString(titles[i]);
                } else {
                    ss = new SpannableString(titles[i] + "\n" + values[i]);
                }
                ss.setSpan(new AbsoluteSizeSpan(titleSize), 0, titles[i].length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                ss.setSpan(new ForegroundColorSpan(Color.RED), titles[i].length(), ss.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            if (drawables == null) {
                drawables = new int[count];
            }
            if (Math.abs(curAngle - 3 * Math.PI / 2) < 0.1 || Math.abs(curAngle - Math.PI / 2) < 0.1) {
                if (Math.abs(curAngle - Math.PI / 2) < 0.1) {
                    drawMultiLinesTextAndIcon(canvas, x - MAX_TEXT_WIDTH / 2, y, ss, drawables[i], 1, i);
                } else if (Math.abs(curAngle - Math.PI * 3 / 2) < 0.1) {
                    drawMultiLinesTextAndIcon(canvas, x - MAX_TEXT_WIDTH / 2, y, ss, drawables[i], -1, i);
                } else {
                    drawMultiLinesTextAndIcon(canvas, x - MAX_TEXT_WIDTH / 2, y, ss, drawables[i], 0, i);
                }
            } else if (curAngle >= 0 && curAngle < Math.PI / 2) {
                drawMultiLinesTextAndIcon(canvas, x + descPadding, y, ss, drawables[i], 0, i);
            } else if (curAngle > 3 * Math.PI / 2 && curAngle <= Math.PI * 2) {
                drawMultiLinesTextAndIcon(canvas, x + descPadding, y, ss, drawables[i], 0, i);
            } else if (curAngle > Math.PI / 2 && curAngle <= Math.PI) {
                drawMultiLinesTextAndIcon(canvas, x - MAX_TEXT_WIDTH, y, ss, drawables[i], 0, i);
            } else if (curAngle >= Math.PI && curAngle < 3 * Math.PI / 2) {
                drawMultiLinesTextAndIcon(canvas, x - MAX_TEXT_WIDTH, y, ss, drawables[i], 0, i);
            }
        }
    }

    public Bitmap getResizeBitmap(int drawable) {
        Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(), drawable);
        if (bitmap == null) {
            return null;
        }
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        if (width <= 0 || height <= 0) {
            return null;
        }
        // 设置想要的大小
        int newWidth = drawableSize;
        int newHeight = drawableSize;
        // 计算缩放比例
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // 取得想要缩放的matrix参数
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        // 得到新的图片
        Bitmap newBm = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix,
                true);
        bitmap.recycle();
        return newBm;
    }

    // 用一种颜色画区域
    private void drawRegion(int position, Canvas canvas, float scale) {
        RedarItem item = mlistRedarItems.get(position);
        canvas.save();
        item.getSinglePaint().setColor(item.getSingleColor());
        if (enabledRegionShader) {
            item.getSinglePaint().setShader(regionShader);
        } else {
            item.getSinglePaint().setShader(null);
        }
        List<Point> list = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            int x, y;
            x = (int) (centerX + scale * item.getPercents()[i] * radius * Math.cos(angle * i + Math.PI / 2));
            y = (int) (centerY - scale * item.getPercents()[i] * radius * Math.sin(angle * i + Math.PI / 2));
            Point p = new Point();
            p.set(x, y);
            list.add(p);
        }

        Path path = new Path();
        for (int i = 0; i < list.size(); i++) {
            if (i == 0) {
                path.moveTo(list.get(i).x, list.get(i).y);
            } else {
                path.lineTo(list.get(i).x, list.get(i).y);
            }
        }
        path.close();
        canvas.drawPath(path, item.getSinglePaint());
        canvas.restore();
    }

    // 多种颜色画区域
    private void drawRegionWithColor(int position, Canvas canvas, float scale) {
        RedarItem item = mlistRedarItems.get(position);
        canvas.save();
        int colorSize = colors.length;
        List<Point> list = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            int x, y;
            x = (int) (centerX + scale * item.getPercents()[i] * radius * Math.cos(angle * i + Math.PI / 2));
            y = (int) (centerY - scale * item.getPercents()[i] * radius * Math.sin(angle * i + Math.PI / 2));
            Point p = new Point();
            p.set(x, y);
            list.add(p);
        }

        Path path = new Path();
        for (int i = 0; i < list.size() - 1; i++) {
            path.reset();
            path.moveTo(centerX, centerY);
            path.lineTo(list.get(i).x, list.get(i).y);
            path.lineTo(list.get(i + 1).x, list.get(i + 1).y);
            path.lineTo(centerX, centerY);
            path.close();
//            dataPaint.setColor(colors[i % colorSize]);
            item.getDataPaint().setColor(item.getDataColor());
            canvas.drawPath(path, item.getDataPaint());
        }
        path.reset();
        path.moveTo(centerX, centerY);
        path.lineTo(list.get(list.size() - 1).x, list.get(list.size() - 1).y);
        path.lineTo(list.get(0).x, list.get(0).y);
        path.lineTo(centerX, centerY);
        path.close();
//        dataPaint.setColor(colors[(list.size() - 1) % colorSize]);
        item.getDataPaint().setColor(item.getDataColor());
        canvas.drawPath(path, item.getDataPaint());
        canvas.restore();
    }

    // 画 多行文字
    public void drawMultiLinesTextAndIcon(Canvas canvas, float x, float y, CharSequence text, int drawable, int verticalValue, int position) {
        int drawableAvaiable = 1;
        try {
            this.getContext().getResources().openRawResource(drawable);
            drawableAvaiable = 1;
        } catch (Exception e) {
            drawableAvaiable = 0;
        }
        int allowWidth = MAX_TEXT_WIDTH - descPadding;
        int rectWidth = allowWidth;
        Rect rect;
        if (drawable != -1) {
            if (allowWidth > drawableSize * drawableAvaiable + drawablePadding) {
                allowWidth = allowWidth - drawableSize * drawableAvaiable - drawablePadding;
            }
        }
        StaticLayout layout = new StaticLayout(text, titlePaint, allowWidth, Layout.Alignment.ALIGN_CENTER, 1.0F, 0.0F, true);
        canvas.save();
        if (verticalValue == 1) {
            canvas.translate(x, y - layout.getHeight() - descPadding);
            rect = new Rect((int) x, (int) (y - layout.getHeight() - descPadding), (int) x + rectWidth, (int) (y - layout.getHeight() - descPadding) + layout.getHeight());
        } else if (verticalValue == -1) {
            canvas.translate(x, y + descPadding);
            rect = new Rect((int) x, (int) (y + descPadding), (int) x + rectWidth, (int) (y + descPadding) + layout.getHeight());
        } else {
            canvas.translate(x, y - layout.getHeight() / 2);
            rect = new Rect((int) x, (int) (y - layout.getHeight() / 2), (int) x + rectWidth, (int) (y - layout.getHeight() / 2) + layout.getHeight());
        }
        titleRects.set(position, rect);
        layout.draw(canvas);
        canvas.restore();//别忘了restore

        // 绘制图标
        if (drawableSize * drawableAvaiable != 0) {
            Bitmap bitmap = getResizeBitmap(drawable);
            if (bitmap != null) {
                if (verticalValue == 1) {
                    canvas.drawBitmap(bitmap, x + layout.getWidth(), y - drawableSize * drawableAvaiable / 2 - layout.getHeight() / 2 - descPadding, titlePaint);
                } else if (verticalValue == -1) {
                    canvas.drawBitmap(bitmap, x + layout.getWidth(), y + descPadding + layout.getHeight() / 2 - drawableSize * drawableAvaiable / 2, titlePaint);
                } else {
                    canvas.drawBitmap(bitmap, x + layout.getWidth(), y - drawableSize * drawableAvaiable / 2, titlePaint);
                }
                bitmap.recycle();
            }
        }

    }

    public void loadAnimation(boolean enabled) {
        if (!enabled) {
            currentScale = 1;
            invalidate();
        } else {
            ValueAnimator valueAnimator = ValueAnimator.ofFloat(0.3f, 1.0f);
            valueAnimator.setInterpolator(new LinearInterpolator());
            valueAnimator.setDuration(animDuration);
            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    currentScale = (float) animation.getAnimatedValue();
                    invalidate();
                }
            });
            valueAnimator.start();
        }
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                int x = (int) event.getX();
                int y = (int) event.getY();
                int intIsClick = 0;
                for (int i = 0; i < titleRects.size(); i++) {
                    mintSelectX = x;
                    mintSelectY = y;
                    mintSelectParent = i;
                    mintSelectChild = -2;
                    Rect rect = titleRects.get(i);
                    if (rect != null && rect.contains(x, y)) {
                        intIsClick++;
                        if (enabledTitlePop) {

                            if (onCirclePop != null) {
                                mvTitlePop = onCirclePop.onTitleClick(i, i, x, y);
                            }
                            if (mvTitlePop == null) {
                                mvTitlePop = LayoutInflater.from(getContext()).inflate(R.layout.popup_card, null);
                                TextView title = (TextView) mvTitlePop.findViewById(R.id.tv_title_name);
                                title.setText(titles[i]);
                                PullListView list = (PullListView) mvTitlePop.findViewById(R.id.lv_data);
                                RadarPopAdapter adapter = new RadarPopAdapter(getContext());
                                list.setAdapter(adapter);
                                adapter.setData(i, -1, mlistRedarItems);
                                setListViewHeightBasedOnChildren(list);
                            }
                            mbtTitlePop = getViewBitmap(mvTitlePop);
                        }
                        if (onTitleClickListener != null) {
                            onTitleClickListener.onTitleClick(XRadarView.this, i, x, y, rect);
                            invalidate();
                            return true;
                        }
                    }
                }
                for (int l = 0; l < mlistRedarItems.size(); l++) {
                    if (!mlistRedarItems.get(l).isShow()) {
                        continue;
                    }
                    RedarItem redarItem = mlistRedarItems.get(l);
                    for (int i = 0; i < redarItem.getCircleRects().size(); i++) {
                        mintSelectX = x;
                        mintSelectY = y;
                        mintSelectParent = i;
                        mintSelectChild = l;
                        Rect circleRect = redarItem.getCircleRects().get(i);
                        if (circleRect != null && circleRect.contains(x, y)) {
                            intIsClick++;
                            if (enabledCirclePop) {
                                if (onCirclePop != null) {
                                    mvTitlePop = onCirclePop.onChildClick(l, i, x, y);
                                }
                                if (mvTitlePop == null) {
                                    mvTitlePop = LayoutInflater.from(getContext()).inflate(R.layout.popup_card, null);
                                    TextView title = (TextView) mvTitlePop.findViewById(R.id.tv_title_name);
                                    title.setText(titles[i]);
                                    PullListView list = (PullListView) mvTitlePop.findViewById(R.id.lv_data);
                                    RadarPopAdapter adapter = new RadarPopAdapter(getContext());
                                    list.setAdapter(adapter);
                                    adapter.setData(l, i, mlistRedarItems);
                                    setListViewHeightBasedOnChildren(list);
                                }
                                mbtTitlePop = getViewBitmap(mvTitlePop);
                            }
                            if (onTitleClickListener != null) {
                                onTitleClickListener.onCircleClick(XRadarView.this, l, i, x, y, circleRect);
                                invalidate();
                                return true;
                            }
                        }
                    }
                }
                if (intIsClick == 0) {
                    mintSelectX = -1;
                    mintSelectY = -1;
                    mintSelectParent = -1;
                    mintSelectChild = -1;
                }
                invalidate();
                break;
        }
        return super.onTouchEvent(event);
    }


    OnTitleClickListener onTitleClickListener;
    OnCirclePop onCirclePop;

    public OnCirclePop getOnCirclePop() {
        return onCirclePop;
    }

    public void setOnCirclePop(OnCirclePop onCirclePop) {
        this.onCirclePop = onCirclePop;
    }

    public void setOnTitleClickListener(OnTitleClickListener onTitleClickListener) {
        this.onTitleClickListener = onTitleClickListener;
    }

    public interface OnTitleClickListener {
        void onTitleClick(XRadarView view, int position, int touchX, int touchY, Rect titleRect);

        void onCircleClick(XRadarView view, int parent, int position, int touchX, int touchY, Rect titleRect);
    }

    public interface OnCirclePop {
        View onTitleClick(int position, int child, int touchX, int touchY);

        View onChildClick(int position, int child, int touchX, int touchY);
    }

    public void setDrawables(int[] drawables) {
        this.drawables = drawables;
        invalidate();
    }

    public void setPercents(int position, double[] percents) {
        RedarItem item = mlistRedarItems.get(position);
        item.setPercents(percents);
    }

    public void setTitles(CharSequence[] titles) {
        this.titles = titles;
        invalidate();
    }

    public void setValues(CharSequence[] values) {
        this.values = values;
        invalidate();
    }

    public void setColors(int[] colors) {
        this.colors = colors;
        invalidate();
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
        angle = (float) (Math.PI * 2 / count);
        invalidate();
    }

    public int getLayerCount() {
        return layerCount;
    }

    public void setLayerCount(int layerCount) {
        this.layerCount = layerCount;
        invalidate();
    }

    public int getDrawableSize() {
        return drawableSize;
    }

    public void setDrawableSize(int drawableSize) {
        this.drawableSize = drawableSize;
        invalidate();
    }

    public int getDrawablePadding() {
        return drawablePadding;
    }

    public void setDrawablePadding(int drawablePadding) {
        this.drawablePadding = drawablePadding;
        invalidate();
    }

    public int getDescPadding() {
        return descPadding;
    }

    public void setDescPadding(int descPadding) {
        this.descPadding = descPadding;
        invalidate();
    }

    public int getTitleSize() {
        return titleSize;
    }

    public void setTitleSize(int titleSize) {
        this.titleSize = titleSize;
        invalidate();
    }

    public int getDataSize() {
        return dataSize;
    }

    public void setDataSize(int dataSize) {
        this.dataSize = dataSize;
        invalidate();
    }

    public float getRadarPercent() {
        return radarPercent;
    }

    public void setRadarPercent(float radarPercent) {
        this.radarPercent = radarPercent;
        invalidate();
    }

    public int getStartColor() {
        return startColor;
    }

    public void setStartColor(int startColor) {
        this.startColor = startColor;
        invalidate();
    }

    public int getEndColor() {
        return endColor;
    }

    public void setEndColor(int endColor) {
        this.endColor = endColor;
        invalidate();
    }

    public boolean isEnabledAnimation() {
        return enabledAnimation;
    }

    public void setEnabledAnimation(boolean enabledAnimation) {
        this.enabledAnimation = enabledAnimation;
        invalidate();
    }

    public boolean isEnabledShowPoint() {
        return enabledShowPoint;
    }

    public void setEnabledShowPoint(boolean enabledShowPoint) {
        this.enabledShowPoint = enabledShowPoint;
        invalidate();
    }

    public int getCobwebColor() {
        return cobwebColor;
    }

    public void setCobwebColor(int cobwebColor) {
        this.cobwebColor = cobwebColor;
        cobwebPaint.setColor(cobwebColor);
        invalidate();
    }

    public int getLineColor() {
        return lineColor;
    }

    public void setLineColor(int lineColor) {
        this.lineColor = lineColor;
        linePaint.setColor(lineColor);
        invalidate();
    }

    public int getDataColor(int position) {
        RedarItem item = mlistRedarItems.get(position);
        return item.getDataColor();
    }

    public void setDataColor(int position, int dataColor) {
        RedarItem item = mlistRedarItems.get(position);
        item.setDataColor(dataColor);
        item.getDataPaint().setColor(dataColor);
    }

    public int getTitleColor() {
        return titleColor;
    }

    public void setTitleColor(int titleColor) {
        this.titleColor = titleColor;
        titlePaint.setColor(titleColor);
        invalidate();
    }

    public int getPointColor(int position) {
        RedarItem item = mlistRedarItems.get(position);
        return item.getPointColor();
    }

    public void setPointColor(int position, int pointColor) {
        RedarItem item = mlistRedarItems.get(position);
        item.setPointColor(pointColor);
        item.getPointPaint().setColor(pointColor);
    }

    public void setName(int position, String name) {
        RedarItem item = mlistRedarItems.get(position);
        item.setName(name);
    }

    public int getPointRadius() {
        return pointRadius;
    }

    public void setPointRadius(int pointRadius) {
        this.pointRadius = pointRadius;
        invalidate();
    }

    public boolean isEnabledBorder() {
        return enabledBorder;
    }

    public void setEnabledBorder(boolean enabledBorder) {
        this.enabledBorder = enabledBorder;
        invalidate();
    }

    public int getBorderColor(int position) {
        RedarItem item = mlistRedarItems.get(position);
        return item.getBorderColor();
    }

    public void setBorderColor(int position, int borderColor) {
        RedarItem item = mlistRedarItems.get(position);
        item.setBorderColor(borderColor);
        item.getBorderPaint().setColor(borderColor);
    }

    public int getBoundaryWidth() {
        return boundaryWidth;
    }

    public void setBoundaryWidth(int boundaryWidth) {
        this.boundaryWidth = boundaryWidth;
    }

    public boolean isEnabledPolygon() {
        return enabledPolygon;
    }

    public void setEnabledPolygon(boolean enabledPolygon) {
        this.enabledPolygon = enabledPolygon;
        invalidate();
    }

    public int[] getColors() {
        return colors;
    }

    public boolean isCircle() {
        return isCircle;
    }

    public void setCircle(boolean circle) {
        isCircle = circle;
        invalidate();
    }

    public boolean isEnabledShade() {
        return enabledShade;
    }

    public void setEnabledShade(boolean enabledShade) {
        this.enabledShade = enabledShade;
        invalidate();
    }

    public void setShow(int position, boolean show) {
        RedarItem item = mlistRedarItems.get(position);
        item.setShow(show);
        mintSelectX = -1;
        mintSelectY = -1;
        invalidate();
    }

    public boolean isShow(int position) {
        RedarItem item = mlistRedarItems.get(position);

        return item.isShow();
    }

    public boolean isEnabledRadius() {
        return enabledRadius;
    }

    public void setEnabledRadius(boolean enabledRadius) {
        this.enabledRadius = enabledRadius;
        invalidate();
    }

    public boolean isEnabledText() {
        return enabledText;
    }

    public void setEnabledText(boolean enabledText) {
        this.enabledText = enabledText;
        invalidate();
    }

    public int getSingleColor(int position) {
        RedarItem item = mlistRedarItems.get(position);
        return item.getSingleColor();
    }

    public void setSingleColor(int position, int singleColor) {
        RedarItem item = mlistRedarItems.get(position);
        item.setSingleColor(singleColor);
        item.getSinglePaint().setColor(singleColor);
        invalidate();
    }

    public void setRegionShaderConfig(int colors[], float positions[]) {
        this.shaderColors = colors;
        this.shaderPositions = positions;
        requestLayout();
        invalidate();
    }

    public void setEnabledRegionShader(boolean enabled) {
        this.enabledRegionShader = enabled;
        requestLayout();
        invalidate();
    }

    public RectF getPathRect(int position) {
        RedarItem item = mlistRedarItems.get(position);
        List<Point> list = new ArrayList<>();

        for (int i = 0; i < count; i++) {
            int x, y;
            x = (int) (centerX + item.getPercents()[i] * radius * Math.cos(angle * i + Math.PI / 2));
            y = (int) (centerY - item.getPercents()[i] * radius * Math.sin(angle * i + Math.PI / 2));
            Point p = new Point();
            p.set(x, y);
            list.add(p);
        }

        Path path = new Path();
        for (int i = 0; i < list.size(); i++) {
            if (i == 0) {
                path.moveTo(list.get(i).x, list.get(i).y);
            } else {
                path.lineTo(list.get(i).x, list.get(i).y);
            }
        }
        path.close();
        RectF rect = new RectF();
        path.computeBounds(rect, true);
        return rect;
    }

    /**
     * 线条颜色
     */
    public class RedarItem {
        public RedarItem() {
            dataPaint = new Paint();
            dataPaint.setColor(mintDataColor);
            dataPaint.setAntiAlias(true);
            dataPaint.setStyle(Paint.Style.FILL_AND_STROKE);

            singlePaint = new Paint();
            singlePaint.setColor(mintSingleColor);
            singlePaint.setAntiAlias(true);
            singlePaint.setStyle(Paint.Style.STROKE);

            pointPaint = new Paint();
            pointPaint.setStyle(Paint.Style.FILL_AND_STROKE);
            pointPaint.setAntiAlias(true);
            pointPaint.setColor(mintPointColor);

            borderPaint = new Paint();
            borderPaint.setStyle(Paint.Style.FILL_AND_STROKE);
            borderPaint.setAntiAlias(true);
            borderPaint.setColor(mintBorderColor);
            borderPaint.setStrokeWidth(boundaryWidth);

            percents = new double[count];
            circleRects = new ArrayList<>();
            for (int i = 0; i < count; i++) {
                circleRects.add(null);
            }
        }

        /**
         * 当前这条线是否显示
         */
        private boolean isShow = true;
        /**
         * 当前这条线的名称
         */
        private String name;
        /**
         * 记录当前这条线的子坐标点
         */
        private List<Rect> circleRects;
        /**
         * 每种属性的值（0~1.0）
         */
        private double percents[];
        /**
         * 如果不是多色区域，是单一的颜色
         */
        private int singleColor;
        /**
         * 雷达图渐变颜色数组
         */
        private int[] shaderColors;
        /**
         * 雷达图渐变颜色各种颜色分布的位置
         */
        private float[] shaderPositions;
        /**
         * 雷达选择线
         */
        private Paint singlePaint;
        /**
         * 数据画笔
         */
        private Paint dataPaint;
        /**
         * 区域渐变shader
         */
        private Shader regionShader;
        /**
         * 线画笔
         */
        private Paint borderPaint;
        /**
         * 点画笔
         */
        private Paint pointPaint;
        /**
         * 边界线颜色
         */
        private int borderColor;
        /**
         * 圆点颜色
         */
        private int pointColor;
        /**
         * 数据值文本颜色
         */
        private int dataColor;

        public boolean isShow() {
            return isShow;
        }

        public void setShow(boolean show) {
            isShow = show;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getDataColor() {
            return dataColor;
        }

        public void setDataColor(int dataColor) {
            this.dataColor = dataColor;
        }

        public int getBorderColor() {
            return borderColor;
        }

        public void setBorderColor(int borderColor) {
            this.borderColor = borderColor;
        }

        public int getPointColor() {
            return pointColor;
        }

        public void setPointColor(int pointColor) {
            this.pointColor = pointColor;
        }

        public List<Rect> getCircleRects() {
            return circleRects;
        }

        public void setCircleRects(List<Rect> circleRects) {
            this.circleRects = circleRects;
        }

        public double[] getPercents() {
            return percents;
        }

        public void setPercents(double[] percents) {
            this.percents = percents;
        }

        public int getSingleColor() {
            return singleColor;
        }

        public void setSingleColor(int singleColor) {
            this.singleColor = singleColor;
        }

        public int[] getShaderColors() {
            return shaderColors;
        }

        public void setShaderColors(int[] shaderColors) {
            this.shaderColors = shaderColors;
        }

        public float[] getShaderPositions() {
            return shaderPositions;
        }

        public void setShaderPositions(float[] shaderPositions) {
            this.shaderPositions = shaderPositions;
        }

        public Paint getSinglePaint() {
            return singlePaint;
        }

        public void setSinglePaint(Paint singlePaint) {
            this.singlePaint = singlePaint;
        }

        public Paint getDataPaint() {
            return dataPaint;
        }

        public void setDataPaint(Paint dataPaint) {
            this.dataPaint = dataPaint;
        }

        public Shader getRegionShader() {
            return regionShader;
        }

        public void setRegionShader(Shader regionShader) {
            this.regionShader = regionShader;
        }

        public Paint getBorderPaint() {
            return borderPaint;
        }

        public void setBorderPaint(Paint borderPaint) {
            this.borderPaint = borderPaint;
        }

        public Paint getPointPaint() {
            return pointPaint;
        }

        public void setPointPaint(Paint pointPaint) {
            this.pointPaint = pointPaint;
        }
    }

    public List<RedarItem> getRedarItems() {
        return mlistRedarItems;
    }

    public void setRedarItems(List<RedarItem> mlistRedarItems) {
        this.mlistRedarItems = mlistRedarItems;
    }

    public int getRedarItemCount() {
        return redarItemCount;
    }

    public void setRedarItemCount(int redarItemCount) {
        this.redarItemCount = redarItemCount;
        mlistRedarItems.clear();
        for (int i = 0; i < redarItemCount; i++) {
            mlistRedarItems.add(new RedarItem());
        }

    }

    //把布局变成Bitmap
    private Bitmap getViewBitmap(View addViewContent) {

        addViewContent.setDrawingCacheEnabled(true);

        addViewContent.measure(
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
        addViewContent.layout(0, 0,
                addViewContent.getMeasuredWidth(),
                addViewContent.getMeasuredHeight());

        addViewContent.buildDrawingCache();
        Bitmap cacheBitmap = addViewContent.getDrawingCache();
        Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);

        return bitmap;
    }

    public static void setListViewHeightBasedOnChildren(ListView listView) {
        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null) {
            // pre-condition
            return;
        }

        int totalHeight = 0;
        for (int i = 0; i < listAdapter.getCount(); i++) {
            View listItem = listAdapter.getView(i, null, listView);
            listItem.measure(0, 0);
            totalHeight += listItem.getMeasuredHeight();
        }

        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        listView.setLayoutParams(params);
    }
}
